package com.main;

import java.io.*;
import java.math.*;
import java.security.*;
import java.security.spec.*;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class DataSecurity {
	
	

	public void generateKeyPair() throws IOException, InvalidKeySpecException,
			NoSuchAlgorithmException {

		try {

			KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
			kpg.initialize(2048);
			KeyPair kp = kpg.genKeyPair();
			Key publicKey = kp.getPublic();
			Key privateKey = kp.getPrivate();

			KeyFactory fact = KeyFactory.getInstance("RSA");
			RSAPublicKeySpec pub;

			pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
			RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(),
					RSAPrivateKeySpec.class);
			saveToFile("C:\\Workspace\\picSEEK\\XMLRepository\\public.key", pub.getModulus(), pub.getPublicExponent());
			saveToFile("C:\\Workspace\\picSEEK\\XMLRepository\\private.key", priv.getModulus(), priv
					.getPrivateExponent());

		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
			throw e;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			throw e;
		}

	}

	public void saveToFile(String fileName, BigInteger mod, BigInteger exp)
			throws IOException {
		ObjectOutputStream oout = new ObjectOutputStream(
				new BufferedOutputStream(new FileOutputStream(fileName)));
		try {
			oout.writeObject(mod);
			oout.writeObject(exp);
		} catch (Exception e) {
			throw new IOException("Unexpected error", e);
		} finally {
			oout.close();
		}
	}

	PublicKey readPubKeyFromFile(String keyFileName) throws IOException {

		InputStream in = new FileInputStream(keyFileName);

		ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(
				in));
		try {
			BigInteger m = (BigInteger) oin.readObject();
			BigInteger e = (BigInteger) oin.readObject();
			RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
			KeyFactory fact = KeyFactory.getInstance("RSA");
			PublicKey pubKey = fact.generatePublic(keySpec);
			return pubKey;
		} catch (Exception e) {
			throw new RuntimeException("Spurious serialisation error", e);
		} finally {
			oin.close();
		}
	}
	
	PrivateKey readPrivateKeyFromFile(String keyFileName) throws IOException {

		InputStream in = new FileInputStream(keyFileName);

		ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(
				in));
		try {
			BigInteger m = (BigInteger) oin.readObject();
			BigInteger e = (BigInteger) oin.readObject();
			RSAPrivateKeySpec  keySpec = new RSAPrivateKeySpec(m, e);
			KeyFactory fact = KeyFactory.getInstance("RSA");
			PrivateKey pubKey = fact.generatePrivate(keySpec);
			return pubKey;
		} catch (Exception e) {
			throw new RuntimeException("Spurious serialisation error", e);
		} finally {
			oin.close();
		}
	}

	public byte[] rsaEncrypt(byte[] data) {
		PublicKey pubKey;
		byte[] cipherData=null;
		try {
			pubKey = readPubKeyFromFile("C:\\Workspace\\picSEEK\\XMLRepository\\public.key");
			System.out.println("publickey  "+pubKey.getEncoded());
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);
			cipherData = cipher.doFinal(data);
		} catch (Exception e) {
			
			e.printStackTrace();
		}

		return cipherData;
	}
	
	public byte[] rsaDecrypt(byte[] data) {
		PrivateKey privateKey;
		byte[] cipherData=null;
		try {
			privateKey = readPrivateKeyFromFile("C:\\Workspace\\picSEEK\\XMLRepository\\private.key");
			System.out.println("priavtekey "+privateKey.getEncoded());
	
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			cipherData = cipher.doFinal(data);
		} catch (Exception e) {
			
			e.printStackTrace();
		}

		return cipherData;
	}
	
	public static void main(String[] args) {
		
		DataSecurity ds=new DataSecurity();
		try {
			ds.generateKeyPair();
			String apiKey="abc";
			byte[] encryptedApiKey=ds.rsaEncrypt(apiKey.getBytes());
			byte[] decryptedApiKey=ds.rsaDecrypt(encryptedApiKey);
			
			String theString = new String(decryptedApiKey); 
			
			System.out.println(theString);
		} catch (Exception e) {
			 System.out.println(e.getMessage());
			e.printStackTrace();
		} 
	}

}
